#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long;
use Config::IniFiles;
use Shell qw/touch date/;
use IO::File;

my $VERSION="1.02";
my $configFile=undef;
my $dataFile=undef;
my $opt = GetOptions (
	"f|config=s" => \$configFile,    # string
	"d|data=s" => \$dataFile,
	);  # flag

unless ( defined ($configFile) and -f $configFile ) {
	print STDERR "Config file doesn't exists or is not defined !\n";
	exit 1;
}

unless ( defined ($dataFile) and -f $dataFile ) {
	print STDERR "Data file doesn't exists or is not defined !\n";
	exit 2;
}

my %ini;
tie %ini, 'Config::IniFiles', ( -file => $configFile );
my $gsep=$ini{'general'}{'separator'};
my $lsep=$ini{'general'}{'lineSeparator'};
$lsep="\n" if ($lsep eq "newline");
$lsep="\t" if ($lsep eq "tab");
### LINE SEPARATOR : $lsep
my %fields;
my %filesSep;
my %filesTranslate;
#my ($startCol,$startChar);

my $startCol=$ini{'general'}{'startColunm'};
my $startChar=$ini{'general'}{'startChar'};

foreach my $section ( sort grep /File/, keys %ini ) {
	### handling section: $section
	my @files=();
	my @lfields= split/,/, $ini{$section}{'fields'};
	my $name=$ini{'general'}{'outputDirectory'}."/".$ini{$section}{'file'};
	my $zipped=$ini{$section}{'zipped'};
	### File name : $name
	my $h=openFileHandle ( $name, $zipped );
	for my $id (@lfields) {
		push @{$fields{$id}}, $h;
	}
	if (scalar (@lfields) > 1){
		$filesSep{$h}=$ini{$section}{'separator'};
	} else {
		$filesSep{$h}="";
	}
	my $strTrans=$ini{$section}{'translate'};
	my $htrans= eval "{$strTrans};";
	### HASH TRANSLATE : $htrans
	$filesTranslate{$h}=$htrans;
	
}
### SEPARATORS : %filesSep
### FILEDS : %fields
open( SOURCE, "< $dataFile" )
       or die "Couldn't open $dataFile for reading: $!\n";

$startChar='' unless defined $startChar;
$startCol=0 unless defined $startCol;
### startChar: $startChar
### startCol: $startCol
while (<SOURCE>) {
	### LINE : $_
	for ( my $i=0; $i<$startCol; $i++) {
		s/.+?$startChar(.*)$/$1/;
	}
	### LINE : $_
	my @elts=split /$gsep/, trim($_);
	
	#exit 0;	
	my @usedHandlers=();
	my ($line, $item);
	### SPLITTED ELEMENTS : @elts
	for (my $i=1; $i<=scalar(@elts);$i++) {
		### RELATED FIELDS : $fields{$i}
		foreach my $f (@{$fields{$i}}) {
			### FHANDLER: $f
			### WRITING: $elts[$i]
			### WRITING SEPARATOR: $filesSep{$f}
			$line=$elts[$i-1];
			### BEFORE : $line
			### BEFORE : keys %{$filesTranslate{$f}}
			foreach my $t ( keys %{$filesTranslate{$f}} ) {
				### Key : $t
				### Val : ${$filesTranslate{$f}}{$t}
				$item=${$filesTranslate{$f}}{$t};
				$line =~ s/$t/$item/g;
				#$line =~ s/(\\.)/$1/g;
				$line =~ s/\\n/\n/g;
				$line =~ s/\\t/\t/g;
				$line =~ s/\\b/\b/g;
			}				
			### AFTER : $line
			
			unless ($line =~ /^$/) {
				print $f "$line";
			
				print $f $filesSep{$f} if defined $filesSep{$f};
				push @usedHandlers, $f;
			
				### Ligne vide : $line
				### Ecrit dans :  $$f
				#exit;
			}
		}
	}
	my %seen;
  	my @uniqed = grep !$seen{$_}++, @usedHandlers;
	foreach my $fhl (@uniqed) {print $fhl "$lsep";}
}
close(SOURCE);

for my $fh (keys %filesSep) {
	close ($fh);
}

sub trim {
    my $string = shift;
    $string =~ s/^\s+//;
    $string =~ s/\s+$//;
    return $string;
}

sub retrieveTrueFileName{
	my $name=shift;
        $name =~ s/(\%.)-(\d+)/date( "--date \"$2 day ago\"", "+$1")/eg;
	$name =~ s/(\%.)/date("+$1")/eg;
	$name =~ s/\n//g;
	
	return $name;
}

sub openFileHandle {
	    my $file= retrieveTrueFileName shift;
	    my $zipped=shift;
	    my $handle = new IO::File;
	    if (defined $zipped and $zipped==1) {
	    	open ($handle, "| gzip >> $file.gz"); #  we write to a pipe 
	    } else {
	    	touch $file unless ( -f $file );
	    	die "$file : $@" unless ( -f $file );
	    	open($handle, ">>$file") or die "$file: $!";
	    }
	    #$handle->autoflush(1);
	    return $handle;
}
exit 0;
